package com.wyh.controller.g3controller;


import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.protobuf.ServiceException;
import com.wyh.common.result.Result;

import com.wyh.domain.dto.gfive.LoginUser;
import com.wyh.domain.enums.g3enums.BillTypeEnum;
import com.wyh.domain.po.g3po.G3Page;
import com.wyh.domain.vo.g3vo.BasicChargingInfoVo;
import com.wyh.domain.vo.g3vo.ChargInfoVo;
import com.wyh.domain.vo.g3vo.ChargingVo;
import com.wyh.domain.vo.g3vo.ExcelInfoVo;
import com.wyh.mapper.g3mapper.G3ChargingMapper;
import com.wyh.security.gfive.utils.SecurityUtils;
import com.wyh.service.g3service.ChargingService;
import com.wyh.utils.g3utils.ExcelUtils;
import com.wyh.utils.g3utils.UpdateUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

import static com.wyh.common.enums.ResultCodeEnum.PARAM_LOST_ERROR;


@RestController
@Api(tags = "计费生成")
@RequestMapping("/leadin")
public class UploadController {


    @Autowired
    ChargingService chargingService;

    @Autowired
    G3ChargingMapper g3ChargingMapper;

    @Transactional
    @ApiOperation("Excel导入")
    @PostMapping("/uploading")
    public Result upload(@Param(value = "Excel文件") MultipartFile file,
                         HttpServletRequest request) throws IOException, ServiceException {

        if (request != null) {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Integer userid = loginUser.getUser().getId();
            if (userid == null) {
                return Result.error();
            }
            if (file==null||file.isEmpty()) {
                return Result.error();
            }

//            List<ExcelInfoVo> excelData = ExcelUtils.getExcelModelData(file.getInputStream(), ExcelInfoVo.class);
            List<ExcelInfoVo> excelData = ExcelUtils.readExcel(file.getInputStream());

            //与前端强调，判断data是否为空判断是否成功
            if (ExcelUtils.judgeErrorTorF(excelData)) {
                //进行插入
                //判断表中内容是否存在 两个判断，是否存在，三表名称、编号
                for (ExcelInfoVo excelDatum : excelData) {
                    excelDatum.setResult(false);
                    Integer organizationId = g3ChargingMapper.findOrganizationId(excelDatum.getOrganizationName());//组织id
                    if (organizationId != null) {
                        if (excelDatum.getParkName() != null) {
                            //园区名称
                            //通过园区名和组织id查园区id
                            Integer parkName = g3ChargingMapper.findPId(excelDatum.getParkName(), organizationId);
                            if (parkName != null) {
                                ExcelInfoVo excelInfoVo = chargingService.flats(excelDatum, parkName, userid);
                                if (!excelInfoVo.isResult()) {
                                    excelDatum.setErrorReason((excelInfoVo.getErrorReason() != null ? excelInfoVo.getErrorReason() : "") + (excelDatum.getErrorReason() != null ? excelDatum.getErrorReason() : ""));
                                    return Result.errorCharging(excelData);
                                }
                            } else {
                                excelDatum.setErrorReason("未查询到该园区," + (excelDatum.getErrorReason() != null ? excelDatum.getErrorReason() : ""));
                                return Result.errorCharging(excelData);
                            }

                        } else {//这是没有园区的情况

                            ExcelInfoVo excelInfoVo = chargingService.flats(excelDatum, organizationId, userid);
                            if (excelInfoVo.isResult()) {
                                return Result.success();
                            }
                        }
                    } else {
                        excelDatum.setErrorReason("未查询到该组织," + (excelDatum.getErrorReason() != null ? excelDatum.getErrorReason() : ""));
                        return Result.error(excelData);
                    }
                }

                return Result.success(excelData.size());
            } else {
                List<ExcelInfoVo> excelInfoVos = ExcelUtils.judgeError(excelData);
                return Result.error(excelInfoVos);
            }
        } else {
            return Result.error();
        }
    }


    @ApiOperation("导出Excel")
    @PostMapping("download")
    public Result download(HttpServletResponse response, @RequestBody List<ExcelInfoVo> excelInfoVos) throws IOException {
        if (excelInfoVos.isEmpty()) {
            return Result.error();
        }
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("导入错误信息", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), ExcelInfoVo.class).sheet("模板").doWrite(excelInfoVos);

        return Result.success();
    }


    @ApiOperation("导出Excel导入模版")
    @PostMapping("exceltemplate")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功下载Excel导入模版"),
            @ApiResponse(code = 500, message = "服务器内部错误，导出失败")
    })
    public ResponseEntity<String> download(HttpServletResponse response) throws IOException {
        Workbook workbook = new XSSFWorkbook(); // 使用XSSFWorkbook支持.xlsx格式
        Sheet sheet = workbook.createSheet("导入模板");
        // 第二行列名，指定列使用红色字体
        List<String> data = Arrays.asList(
                "组织名称", "园区名称", "楼盘名称", "组团名称", "楼栋名称",
                "单元", "楼层名称", "资源名称", "客户名称", "费项名称",
                "计费期间起", "计费期间止", "计费账期", "三表名称",
                "三表编号", "三表类型", "表倍率", "上期用量",
                "上期抄表时间", "三表上期读数", "三表本期读数",
                "用量", "单价", "应收金额"
        );
        Row headerRow = sheet.createRow(1);
        int[] redFontColumns = {0, 2, 6, 7, 8, 9, 10, 11, 12, 22, 23}; // 指定红色字体的列索引
        CellStyle redStyle = UpdateUtils.createRedFontCellStyle(workbook); // 新增方法：创建红色字体样式
        // 设置第一行注释
        Row attentionRow = sheet.createRow(0);
        Cell attentionCell = attentionRow.createCell(0);
        attentionCell.setCellValue("注：红色为必填项");
        attentionCell.setCellStyle(redStyle);
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1)); // 合并单元格

        for (int i = 0; i < data.size(); i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(data.get(i));
            if (UpdateUtils.contains(redFontColumns, i)) {
                cell.setCellStyle(redStyle);
            }
        }
        // 设置响应头进行下载
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("导入模版", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        try {
            workbook.write(response.getOutputStream());
            workbook.close();
            return ResponseEntity.ok("导出成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("导出失败");
        }
    }


    //计费生成页查询条件基础数据
    @ApiOperation("计费生成查询基础条件数据")
    @PostMapping("/basiccharging")
    public Result BasicChargingInfo() {
        BasicChargingInfoVo chargingInfoVo = new BasicChargingInfoVo();
        chargingInfoVo.setPropertyNames(g3ChargingMapper.findPropertyName());
        chargingInfoVo.setResourceNames(g3ChargingMapper.findResourceName());
        chargingInfoVo.setBillingItemsNames(g3ChargingMapper.findBillingItemsName());
        chargingInfoVo.setBillingNatures(BillTypeEnum.getAllBillingTypes());
        return Result.success(chargingInfoVo);
    }


    //计费生成页面查询
    @ApiOperation("计费生成页面查询")
    @PostMapping("/chargegeneration")
    public Result<ChargInfoVo> findListByCondition(@RequestBody BasicChargingInfoVo basicInfo) {
        ChargInfoVo chargInfoVo = new ChargInfoVo();
        G3Page g3Page = basicInfo.getG3Page();
        if (g3Page.getCurrentPage() == 0 || g3Page.getPageSize() == 0) {
            return Result.error(PARAM_LOST_ERROR);
        }


        PageHelper.startPage(g3Page.getCurrentPage(), g3Page.getPageSize());

        List<ChargingVo> listByCondition = g3ChargingMapper.findListByCondition(basicInfo.getPropertyname(),
                basicInfo.getResourcename(), basicInfo.getBillingitemsname(),
                basicInfo.getBillingnature(), basicInfo.getFrontupdatetime(), basicInfo.getLaterupdatetime(),
                basicInfo.getMinreceivable(),
                basicInfo.getMaxreceivable(), basicInfo.getCustomername(), basicInfo.getState(),
                basicInfo.getStartmonth(), basicInfo.getEndmonth()
        );

        PageInfo<ChargingVo> chargingVoPageInfo = new PageInfo<>(listByCondition);
        long total = chargingVoPageInfo.getTotal();


        chargInfoVo.setChargingVos(listByCondition);
        chargInfoVo.setTotal(total);



        if (!listByCondition.isEmpty()) {
            for (ChargingVo chargingVo : listByCondition) {
                chargingVo.setBillingNatureType(BillTypeEnum.getByCode(chargingVo.getBillingnature()));
            }
            return Result.success(chargInfoVo);
        } else {
            return Result.error("", "没有数据");
        }
    }

}
